﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

namespace CoreCommon
{
    /// <summary>
    /// Содержит общие функции безопасности
    /// </summary>
    public class Security
    {
        /// <summary>
        /// Возвращает md5 исполняемого файла
        /// </summary>
        public static string GetSelfHash()
        {

            try
            {
                HashAlgorithm sha256 = new SHA256Managed();
                using(Stream fileStream = new FileStream(Application.ExecutablePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                {
                    byte[] b = new byte[100000];
                    byte[] garbage = new byte[100000];
                    int n;
                    while((n = fileStream.Read(b, 0, b.Length)) > 0)
                    {
                        sha256.TransformBlock(b, 0, n, garbage, 0);
                    }
                    sha256.TransformFinalBlock(b, 0, 0);
                    return BitConverter.ToString(sha256.Hash).Replace("-", "");
                }
            }
            catch(Exception err)
            {
                throw new CoreException(ErrType.Critical, "Ошибка при получении хеша исполняемого файла",  err);
            }
        }

        /// <summary>
        /// Дешифровка по методу AES
        /// </summary>
        /// <param name="text">Текст для дешифровки</param>
        /// <param name="AesIV">Вектор</param>
        /// <param name="AesKey">Ключ</param>
        /// <returns>Дешифрованный текст</returns>
        public static string Decript_AES(string text, string AesIV, string AesKey)
        {
            using (AesManaged am = new AesManaged())
            {
                am.BlockSize = 128;
                am.KeySize = 128;
                am.IV = Encoding.ASCII.GetBytes(AesIV);
                am.Key = Encoding.ASCII.GetBytes(AesKey);
                am.Mode = CipherMode.CBC;
                am.Padding = PaddingMode.PKCS7;

                byte[] src = System.Convert.FromBase64String(text);
                using (ICryptoTransform decrypt = am.CreateDecryptor())
                {
                    byte[] dest = decrypt.TransformFinalBlock(src, 0, src.Length);
                    return Encoding.ASCII.GetString(dest);
                }
            }
        }

        /// <summary>
        /// Шифрование строки методом AES
        /// </summary>
        /// <param name="text">Текст для шифрования</param>
        /// <param name="AesIV">Вектор</param>
        /// <param name="AesKey">Ключ</param>
        /// <returns>Шифрованный текст</returns>
        public static string Encript_AES(string text, string AesIV, string AesKey)
        {
            using (AesManaged am = new AesManaged())
            {
                am.BlockSize = 128;
                am.KeySize = 128;
                am.IV = Encoding.ASCII.GetBytes(AesIV);
                am.Key = Encoding.ASCII.GetBytes(AesKey);
                am.Mode = CipherMode.CBC;
                am.Padding = PaddingMode.PKCS7;

                byte[] src = Encoding.ASCII.GetBytes(text);
                using (ICryptoTransform encrypt = am.CreateEncryptor())
                {
                    byte[] dest = encrypt.TransformFinalBlock(src, 0, src.Length);
                    return Convert.ToBase64String(dest);
                }
            }
        }
    }
}
